﻿using System;
using UnityEngine;
using UnityEngine.UI;

public class JoyStick : IJoyStick {

    public RectTransform baseImage;
    public RectTransform topImage;
    public RectTransform directionIndicator;

    private float sensity = 2;//灵敏度，输出值到达最值需要用的时间有关

    [Range(0.1f, 1f)]
    public float uselessZone = 0.3f;//无效区域，从圆心开始算，到半径0.3倍为止都是无效区域

    private float _baseRadius;
    private float _power;//[0, 1]摇杆偏离中心点的距离，模拟按键按下的力度
    private float _holdTime;//推动摇杆持续的时间
    private bool _isStartedHolding;

    void Awake () {
        //SetActive(false);
    }
	
    void Update()
    {

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Application.Quit();
        }

        if (_isStartedHolding)
        {
            _holdTime += Time.deltaTime;
            float deltaValue = _holdTime * sensity;
            inputMoveVal = Mathf.Clamp(inputMoveVal + deltaValue, 0, 1);
        }

#if UNITY_STANDALONE_WIN || UNITY_EDITOR

        isFireDown = Input.GetButtonDown("Fire1");
        isFirePressing = Input.GetButton("Fire1");
        isFireUp = Input.GetButtonUp("Fire1");

        if (Input.GetMouseButton(0))
        {
            Vector3 mousePos = Input.mousePosition;
            if (Input.GetMouseButtonDown(0))
            {
                //transform.position = mousePos;
                gameObject.SetActive(true);
            }
            else
            {
                Accept(mousePos);
                //Debug.Log("joyStick output=" + _joyStickReactive.getHorizontalValue());
            }
        }
        if (Input.GetMouseButtonUp(0))
        {
            Reset();
        }

        if(Input.GetButton("Left"))
        {
            Accept(new Vector3(baseImage.transform.position.x-40, baseImage.transform.position.y +40, baseImage.transform.position.z));
        }
        if (Input.GetButton("Right"))
        {
            Accept(new Vector3(baseImage.transform.position.x + 40, baseImage.transform.position.y - 40, baseImage.transform.position.z));
        }
        if (Input.GetButton("Up"))
        {
            Accept(new Vector3(baseImage.transform.position.x + 40, baseImage.transform.position.y + 40, baseImage.transform.position.z));
        }
        if (Input.GetButton("Down"))
        {
            Accept(new Vector3(baseImage.transform.position.x - 40, baseImage.transform.position.y - 40, baseImage.transform.position.z));
        }
        if(Input.GetButtonUp("Left") || Input.GetButtonUp("Right") || Input.GetButtonUp("Up") || Input.GetButtonUp("Down"))
        {
            Reset();
        }

#endif

#if UNITY_ANDROID

        bool hasRightTouch = false;
        Touch rightTouch = new Touch();
        Touch[] touchs = Input.touches;
        for (int i = 0; i < touchs.Length && i < 2; i++)
        {
            Touch t = touchs[i];
            if (!hasRightTouch && t.position.x > 900)
            {
                rightTouch = t;
                hasRightTouch = true;
                Debug.Log("Fire!!!");
            }
        }
        if (hasRightTouch)
        {
            isFireDown = rightTouch.phase == TouchPhase.Began;
            isFirePressing = rightTouch.phase == TouchPhase.Moved;
            isFireUp = rightTouch.phase == TouchPhase.Ended;
        }

        bool hasLeftTouch = false;
        Touch leftTouch = new Touch();
        for (int i = 0; i < touchs.Length && i < 2; i++)
        {
            Touch t = touchs[i];
            if (!hasLeftTouch && t.position.x <= 900)
            {
                leftTouch = t;
                hasLeftTouch = true;
            }
        }

        if (hasLeftTouch)
        {
            Vector3 mousePos = leftTouch.position;
            if (leftTouch.phase == TouchPhase.Began)
            {
                transform.position = mousePos;
                gameObject.SetActive(true);
                //_joyStickReactive.StartAccept();
            }
            else if (leftTouch.phase == TouchPhase.Moved)
            {
                Accept(mousePos);
                //Debug.Log("joyStick output=" + _joyStickReactive.getHorizontalValue());
            }
            else if (leftTouch.phase == TouchPhase.Ended)
            {
                Reset();
            }
        }
#endif

    }

    private void StartAccept()
    {
        _isStartedHolding = true;
        _holdTime = 0;
        inputMoveVal = 0;
        directionIndicator.gameObject.SetActive(true);
    }

    public void Accept(Vector3 desiredPoint)
    {
        _baseRadius = baseImage.rect.width * baseImage.lossyScale.x / 2;

        Vector3 dir = desiredPoint - baseImage.transform.position;

        if (!_isStartedHolding && dir.magnitude >= _baseRadius*uselessZone)
        {
            StartAccept();
        }
        
        if(_isStartedHolding)
        {
            if(dir.magnitude < _baseRadius * uselessZone)
            {
                FinishAccept();
            }
            else
            {
                inputDirection = dir;

                coarseDirection = convertCoarseDirection(dir);

                setIndicatorRotation(coarseDirection);
            }
        }

        //Debug.Log("dir="+_direction);
        if (dir.magnitude > _baseRadius)
        {
            float y = dir.y / dir.magnitude * _baseRadius;
            float x = dir.x / dir.magnitude * _baseRadius;
            topImage.transform.position = baseImage.transform.position + new Vector3(x, y, 0);
        }else
        {
            topImage.transform.position = desiredPoint;
        }
    }

    private void setIndicatorRotation(Vector3 coarseDirection)
    {
        float zRotation = 0;
        if (coarseDirection == Vector3.forward)
        {
            zRotation = 180f;
        }
        else if (coarseDirection == Vector3.back)
        {
            zRotation = 0f;
        }
        else if (coarseDirection == Vector3.left)
        {
            zRotation = 270f;
        }
        else if (coarseDirection == Vector3.right)
        {
            zRotation = 90f;
        }
        directionIndicator.rotation = Quaternion.Euler(0, 0, zRotation);
    }

    private void FinishAccept()
    {
        _holdTime = 0;
        inputMoveVal = 0;
        _isStartedHolding = false;
        directionIndicator.gameObject.SetActive(false);
    }

    public void Reset()
    {
        FinishAccept();
        topImage.transform.position = baseImage.transform.position;
    }

    public static Vector3 convertCoarseDirection(Vector3 direction)
    {
        Vector3 eularDir = Quaternion.LookRotation(direction).eulerAngles;

        //Debug.Log("eularDir.x=" + eularDir.x + " eularDir.y=" + eularDir.y);

        //if (eularDir.x >= 270f && eularDir.x <= 315f)
        //{
        //    return 180f;
        //}
        //else if (eularDir.x >= 45 && eularDir.x <= 90)
        //{
        //    return 0f;
        //}
        //else if (eularDir.y >= 200f)
        //{
        //    return 270f;
        //}
        //else if (eularDir.y >= 80f)
        //{
        //    return 90f;
        //}
        //return 0f;

        if (eularDir.x >= 270f && eularDir.x <= 360f && eularDir.y<100)
        {
            return Vector3.forward;
        }
        else if (eularDir.x >= 0 && eularDir.x <= 90 && eularDir.y>200)
        {
            return Vector3.back;
        }
        else if (eularDir.y >= 200f)
        {
            return Vector3.left;
        }
        else if (eularDir.y < 100f)
        {
            return Vector3.right;
        }
        return Vector3.forward;
    }

    public override void SetActive(bool active)
    {
        Debug.Log("j setActive="+active);
        gameObject.SetActive(active);
    }
}
